package hn.sigit.interop.gmlproducers;


import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.deegree.feature.GenericFeature;
import org.deegree.geometry.points.Points;
import org.deegree.geometry.standard.points.JTSPoints;
import org.deegree.gml.feature.GMLFeatureWriter;
import org.deegree.cs.CRS;
import org.deegree.cs.exceptions.TransformationException;
import org.deegree.cs.exceptions.UnknownCRSException;

import com.vividsolutions.jts.geom.CoordinateSequence;


public abstract class GMLProducer<T> {
	public static final String DEFAULT_PREFIX = "sigit";
	public static final String NAMESPACE = "http://www.sigit.hn/sigit-parcel";
	
	private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
	
	private String jurisdictionCode;
	private T objectFeature;
	

	protected static QName newQName(String localPart) {
		return new QName(NAMESPACE, localPart, DEFAULT_PREFIX);
	}
	
	protected static CRS getWorkingCRS() {
		return new CRS("EPSG:32616");
	}
	
	protected static Points getAsPoints( CoordinateSequence seq, CRS crs ) {
        return new JTSPoints( crs, seq );
    }
	
	protected String nvl(String txt) {
		return txt != null ? txt : "";
	}
	
	protected String xsDateTime(Date date) {
		if (date == null) return "";
		
		return sdf.format(date);
	}
	
	protected static void startStreamWriter(XMLStreamWriter xtw) throws XMLStreamException {
        xtw.setPrefix("gml", "http://www.opengis.net/gml");
        xtw.setPrefix("xlink", "http://www.w3.org/1999/xlink");
        xtw.setPrefix("sigit", NAMESPACE);

        
        xtw.writeStartDocument("utf-8", "1.0");
        
        xtw.writeStartElement("http://www.opengis.net/gml", "FeatureCollection");
        xtw.writeNamespace("gml", "http://www.opengis.net/gml");
        xtw.writeNamespace("xlink", "http://www.w3.org/1999/xlink");
        xtw.writeNamespace("sigit", NAMESPACE);
        
        xtw.writeStartElement("http://www.opengis.net/gml", "featureMembers");
	}
	protected static void endStreamWriter(XMLStreamWriter xtw) throws XMLStreamException {
		xtw.writeEndElement();
		xtw.writeEndElement();
		xtw.writeEndDocument();
	}
	
	
	
	protected String getJurisdictionCode() {
		return jurisdictionCode;
	}

	protected T getObjectFeature() {
		return objectFeature;
	}

	protected abstract GenericFeature buildFeature();
	
	public GMLProducer(String jurisdictionCode, T objectFeature) {
		this.jurisdictionCode = jurisdictionCode;
		this.objectFeature = objectFeature;
	}

	public final void produceXml(OutputStream os) throws IOException {
		GenericFeature gf = buildFeature();
        XMLOutputFactory xof = XMLOutputFactory.newInstance();

        try {
        	XMLStreamWriter xtw = xof.createXMLStreamWriter(os);
	        
        	startStreamWriter(xtw);
	        
			GMLFeatureWriter gmlFeatureWriter = new GMLFeatureWriter(xtw, getWorkingCRS());
			gmlFeatureWriter.export(gf);

			endStreamWriter(xtw);
			
	        xtw.flush();
	        xtw.close();
        }
        catch (XMLStreamException xmlse) {
        	throw new IOException(xmlse);
        }
        catch (TransformationException te) {
        	throw new IOException(te);
        }
        catch (UnknownCRSException ucrse) {
        	throw new IOException(ucrse);
        }
	}
}
